{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "992c4695-ec4f-428d-bd05-fb3b5fbd70f4",
   "metadata": {},
   "source": [
    "# How to use the prebuilt ReAct agent"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0fcced0-9767-412f-90f9-7f3cd618ff90",
   "metadata": {},
   "source": [
    "In this how-to we'll create a simple [ReAct](https://arxiv.org/abs/2210.03629) agent app that can check the weather. The app consists of an agent (LLM) and tools. As we interact with the app, we will first call the agent (LLM) to decide if we should use tools. Then we will run a loop:  \n",
    "\n",
    "1. If the agent said to take an action (i.e. call tool), we'll run the tools and pass the results back to the agent\n",
    "2. If the agent did not ask to run tools, we will finish (respond to the user)\n",
    "\n",
    "<div class=\"admonition warning\">\n",
    "    <p class=\"admonition-title\">Prebuilt Agent</p>\n",
    "    <p>\n",
    "Please note that here will we use a prebuilt agent. One of the big benefits of LangGraph is that you can easily create your own agent architectures. So while it's fine to start here to build an agent quickly, we would strongly recommend learning how to build your own agent so that you can take full advantage of LangGraph.\n",
    "    </p>\n",
    "</div>   "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7be3889f-3c17-4fa1-bd2b-84114a2c7247",
   "metadata": {},
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a213e11a-5c62-4ddb-a707-490d91add383",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture --no-stderr\n",
    "%pip install -U langgraph langchain-openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "23a1885c-04ab-4750-aefa-105891fddf3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "OPENAI_API_KEY:  ········\n"
     ]
    }
   ],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "\n",
    "def _set_env(var: str):\n",
    "    if not os.environ.get(var):\n",
    "        os.environ[var] = getpass.getpass(f\"{var}: \")\n",
    "\n",
    "\n",
    "_set_env(\"OPENAI_API_KEY\")\n",
    "\n",
    "# Recommended\n",
    "_set_env(\"LANGCHAIN_API_KEY\")\n",
    "os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
    "os.environ[\"LANGCHAIN_PROJECT\"] = \"Create ReAct Agent Tutorial\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03c0f089-070c-4cd4-87e0-6c51f2477b82",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7a154152-973e-4b5d-aa13-48c617744a4c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# First we initialize the model we want to use.\n",
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "model = ChatOpenAI(model=\"gpt-4o\", temperature=0)\n",
    "\n",
    "\n",
    "# For this tutorial we will use custom tool that returns pre-defined values for weather in two cities (NYC & SF)\n",
    "\n",
    "from typing import Literal\n",
    "\n",
    "from langchain_core.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def get_weather(city: Literal[\"nyc\", \"sf\"]):\n",
    "    \"\"\"Use this to get weather information.\"\"\"\n",
    "    if city == \"nyc\":\n",
    "        return \"It might be cloudy in nyc\"\n",
    "    elif city == \"sf\":\n",
    "        return \"It's always sunny in sf\"\n",
    "    else:\n",
    "        raise AssertionError(\"Unknown city\")\n",
    "\n",
    "\n",
    "tools = [get_weather]\n",
    "\n",
    "\n",
    "# Define the graph\n",
    "\n",
    "from langgraph.prebuilt import create_react_agent\n",
    "\n",
    "graph = create_react_agent(model, tools=tools)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00407425-506d-4ffd-9c86-987921d8c844",
   "metadata": {},
   "source": [
    "## Usage\n",
    "\n",
    "First, let's visualize the graph we just created"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "fa16de4c-aac0-4ff4-ab69-60d399f75423",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "16636975-5f2d-4dc7-ab8e-d0bea0830a28",
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_stream(stream):\n",
    "    for s in stream:\n",
    "        message = s[\"messages\"][-1]\n",
    "        if isinstance(message, tuple):\n",
    "            print(message)\n",
    "        else:\n",
    "            message.pretty_print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d187d6b-0fb6-4860-8771-160c3cf403c6",
   "metadata": {},
   "source": [
    "Let's run the app with an input that needs a tool call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9ffff6c3-a4f5-47c9-b51d-97caaee85cd6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "what is the weather in sf\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "Tool Calls:\n",
      "  get_weather (call_jgO5OOUnugRkhRi3wAOHl8Et)\n",
      " Call ID: call_jgO5OOUnugRkhRi3wAOHl8Et\n",
      "  Args:\n",
      "    city: sf\n",
      "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
      "Name: get_weather\n",
      "\n",
      "It's always sunny in sf\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "The weather in San Francisco is currently sunny.\n"
     ]
    }
   ],
   "source": [
    "inputs = {\"messages\": [(\"user\", \"what is the weather in sf\")]}\n",
    "print_stream(graph.stream(inputs, stream_mode=\"values\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "838a043f-90ad-4e69-9d1d-6e22db2c346c",
   "metadata": {},
   "source": [
    "Now let's try a question that doesn't need tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "187479f9-32fa-4611-9487-cf816ba2e147",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================\u001b[1m Human Message \u001b[0m=================================\n",
      "\n",
      "who built you?\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "I was created by OpenAI, a research organization focused on developing and advancing artificial intelligence technology.\n"
     ]
    }
   ],
   "source": [
    "inputs = {\"messages\": [(\"user\", \"who built you?\")]}\n",
    "print_stream(graph.stream(inputs, stream_mode=\"values\"))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
